package com.exam.api.modules.dict.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.exam.api.common.exception.GlobalException;
import com.exam.api.common.utils.BeanHelper;
import com.exam.api.common.web.ResultCode;
import com.exam.api.modules.dict.domain.SysDict;
import com.exam.api.modules.dict.domain.SysDictItem;
import com.exam.api.modules.dict.dto.SysDictDTO;
import com.exam.api.modules.dict.dto.SysDictSearchDTO;
import com.exam.api.modules.dict.mapper.SysDictMapper;
import com.exam.api.modules.dict.service.SysDictItemService;
import com.exam.api.modules.dict.service.SysDictService;
import com.exam.api.modules.dict.vo.SysDictVO;
import jakarta.annotation.Resource;
import org.redisson.api.RedissonClient;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author iaa
 * @description 针对表【sys_dict(字典)】的数据库操作Service实现
 * @createDate 2025-06-17 14:00:38
 */
@Service
public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> implements SysDictService {

    @Resource
    @Lazy
    private SysDictItemService sysDictItemService;
    @Resource
    private RedissonClient redissonClient;

    @Override
    public void createSysDict(SysDictDTO dto) {
        boolean exists = lambdaQuery()
                .eq(SysDict::getCode, dto.getCode())
                .exists();
        if (exists) {
            throw new GlobalException("字典已存在");
        }
        SysDict converter = dto.converter();
        save(converter);
    }

    @Override
    public void updateSysDict(SysDictDTO dto) {
        Long dictId = dto.getId();
        boolean exists = lambdaQuery()
                .ne(SysDict::getId, dictId)
                .eq(SysDict::getCode, dto.getCode())
                .exists();
        if (exists) {
            throw new GlobalException("字典已存在");
        }
        SysDict dict = getOptById(dictId)
                .orElseThrow(() -> new GlobalException("字典不存在"));
        updateById(dto.converter());
    }

    @Override
    public IPage<SysDictVO> pageSysDict(SysDictSearchDTO dto) {
        QueryWrapper<SysDict> query = new QueryWrapper<>();
        query.lambda().like(StrUtil.isNotBlank(dto.getName()), SysDict::getName, dto.getName());
        query.lambda().like(StrUtil.isNotBlank(dto.getCode()), SysDict::getCode, dto.getCode());
        query.lambda().eq(ObjUtil.isNotNull(dto.getStatus()), SysDict::getStatus, dto.getStatus());
        query.lambda().eq(SysDict::getIsDelete, 0);
        query.lambda().orderByDesc(SysDict::getCreateTime);
        return baseMapper.selectPageBy(dto.buildPage(), query);
    }

    @Override
    public void delSysDict(Long dictId) {
        SysDict sysDict = getOptById(dictId)
                .orElseThrow(() -> new GlobalException("字典不存在"));
        removeById(sysDict.getId());
    }

    @Override
    public SysDictVO selectById(Long id) {
        SysDict byId = getById(id);
        return BeanHelper.copyProperties(byId, SysDictVO.class);
    }

    @Transactional
    @Override
    public void deleteBatch(List<Long> ids) {
        removeBatchByIds(ids);
    }

    @Override
    public String getNameById(long l) {
        return lambdaQuery().eq(SysDict::getId, l)
                .select(SysDict::getName)
                .oneOpt()
                .orElseThrow(() -> new GlobalException(ResultCode.DATA_NO_EXIST))
                .getName();
    }

    @Override
    public List<String> listDictValueByCode(String code) {
        return listDictByCode(code).stream().map(SysDictItem::getDictValue).toList();
    }

    @Override
    public List<SysDictItem> listDictByCode(String code) {
        SysDict dict = lambdaQuery()
                .eq(SysDict::getCode, code)
                .one();
        List<SysDictItem> list = sysDictItemService.lambdaQuery()
                .eq(SysDictItem::getDictId, dict.getId())
                .eq(SysDictItem::getIsDelete, 0)
                .orderByDesc(SysDictItem::getSort)
                .list();
        return list;
    }

    @Override
    public List<String> selectCodeByCodeList(List<String> codeList) {
        return lambdaQuery()
                .in(CollUtil.isNotEmpty(codeList), SysDict::getCode, codeList)
                .list()
                .stream().map(SysDict::getCode)
                .toList();
    }
}




